package com.jboltai.util.text;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.RecursiveParserWrapper;
import org.apache.tika.parser.pdf.PDFParserConfig;
import org.apache.tika.sax.BasicContentHandlerFactory;
import org.apache.tika.sax.ContentHandlerFactory;
import org.apache.tika.sax.RecursiveParserWrapperHandler;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class MetadataUtil {
    public static Map<String, FileInfo> docxFileList(File file) {
        Metadata metadata = metadata(file);

        String html = metadata.get("X-TIKA:content");
        if (StrUtil.isBlank(html)) {
            return null;
        }

        Element body = Jsoup.parse(html).body();

        Map<String, FileInfo> map = new HashMap<>();

        body.select("div[data=custom]").forEach(element -> {
            String resourceName = element.attr("id");
            if (StrUtil.isBlank(resourceName)) {
                return;
            }
            String suffix = resourceName.substring(resourceName.lastIndexOf(".") + 1);
            // 图片
            FileInfo fileInfo = new FileInfo();
//            fileInfo.setResourceName(resourceName);
            fileInfo.setFileName(RandomUtil.randomString(6) + "." + suffix);
            fileInfo.setSuffix(suffix);
            map.put(resourceName, fileInfo);
        });
        return map;
    }

    public static Map<String, FileInfo> docFileList(File file) {
        Metadata metadata = metadata(file);

        String html = metadata.get("X-TIKA:content");
        if (StrUtil.isBlank(html)) {
            return null;
        }

        Element body = Jsoup.parse(html).body();

        Map<String, FileInfo> map = new HashMap<>();

        // 先找图片
        body.select("img").forEach(element -> {
            String resourceName = element.attr("src");
            if (StrUtil.isBlank(resourceName)) {
                return;
            }
            resourceName = resourceName.replace("embedded:", "");
            String suffix = resourceName.substring(resourceName.lastIndexOf(".") + 1);
            if ("emf".equals(suffix)) {
                // 富媒体图片
                Element previousElement = element.previousElementSibling();
                String id = previousElement.attr("id");
                String clazz = previousElement.attr("class");
                if (StrUtil.isNotBlank(id) && StrUtil.isNotBlank(clazz) && clazz.equals("embedded")) {
                    FileInfo fileInfo = new FileInfo();
//                    fileInfo.setResourceName(id);
                    map.put(id, fileInfo);
                }
            } else {
                // 图片
                FileInfo fileInfo = new FileInfo();
//                fileInfo.setResourceName(resourceName);
                fileInfo.setFileName(RandomUtil.randomString(6) + "." + suffix);
                fileInfo.setSuffix(suffix);
                map.put(resourceName, fileInfo);
            }
        });

        // 再找附件
        body.select("div[class=package-entry]").forEach(element -> {
            Element h1 = element.child(0);
            if (h1 == null || !h1.is("h1")) {
                return;
            }
            String text = h1.text();
            // 这种为图片, 非附件
            if (text.indexOf("/") < 0) {
                return;
            }
            String[] textArr = text.split("/");
            String id = textArr[0];
            FileInfo fileInfo = map.get(id);
            if (fileInfo == null) {
                return;
            }
            String resourceName = textArr[1];
            String suffix = PathUtil.getSuffixByResourceName(resourceName);
            fileInfo.setSuffix(suffix);
            fileInfo.setFileName(RandomUtil.randomString(6) + "." + suffix);
            map.put(resourceName, fileInfo);
        });
        return map;
    }

    public static Map<String, FileInfo> pdfFileMap(File file) {
        Metadata metadata = metadata(file);

        String html = metadata.get("X-TIKA:content");
        if (StrUtil.isBlank(html)) {
            return null;
        }

        Element body = Jsoup.parse(html).body();

        Map<String, FileInfo> map = new HashMap<>();

        body.select("img").forEach(element -> {
            String resourceName = element.attr("alt");
            String suffix = resourceName.substring(resourceName.lastIndexOf(".") + 1);

            FileInfo fileInfo = new FileInfo();
//            fileInfo.setResourceName(resourceName);
            fileInfo.setFileName(RandomUtil.randomString(6) + "." + suffix);
            fileInfo.setSuffix(suffix);
//            fileInfo.setSkip(false);
            map.put(resourceName, fileInfo);
        });

        body.select("[source=RichMedia]").forEach(element -> {
            if (element.is("div")) {
                String resourceName = element.attr("id");
                String suffix = resourceName.substring(resourceName.lastIndexOf(".") + 1);

                FileInfo fileInfo = new FileInfo();
//                fileInfo.setResourceName(resourceName);
                fileInfo.setFileName(RandomUtil.randomString(6) + "." + suffix);
                fileInfo.setSuffix(suffix);
//                fileInfo.setSkip(false);
                map.put(resourceName, fileInfo);

                // 查找前一个元素, 如果是img标签, 则说明该图片为富媒体图片
                Element previousElement = element.previousElementSibling();
                if (previousElement.is("img")) {
                    resourceName = previousElement.attr("alt");
                    if (map.containsKey(resourceName)) {
//                        map.get(resourceName).setSkip(true);
                    } else {
                        suffix = resourceName.substring(resourceName.lastIndexOf(".") + 1);

                        fileInfo = new FileInfo();
//                        fileInfo.setResourceName(resourceName);
                        fileInfo.setFileName(RandomUtil.randomString(6) + "." + suffix);
                        fileInfo.setSuffix(suffix);
//                        fileInfo.setSkip(false);
                        map.put(resourceName, fileInfo);
                    }
                }
            }
        });

        Map<String, FileInfo> result = new HashMap<>();

        map.forEach((k, v) -> {
//            if (!v.getSkip()) {
//                result.put(k,v);
//            }
        });
        return result;
    }

    private static Metadata metadata(File file) {
        AutoDetectParser parser = new AutoDetectParser();
        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(parser);

        ContentHandlerFactory factory = new BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.HTML, -1);
        RecursiveParserWrapperHandler handler = new RecursiveParserWrapperHandler(factory, 1);

        Metadata metadata = new Metadata();
        ParseContext parseContext = new ParseContext();

        // PDF开启图片提取
        PDFParserConfig pdfParserConfig = new PDFParserConfig();
        pdfParserConfig.setOcrStrategy(PDFParserConfig.OCR_STRATEGY.NO_OCR);
        pdfParserConfig.setExtractInlineImages(true);
        parseContext.set(PDFParserConfig.class, pdfParserConfig);
        parseContext.set(AutoDetectParser.class, parser);

        FileInputStream fis = null;

        try {
            fis = new FileInputStream(file);
            wrapper.parse(fis, handler, metadata, parseContext);
            return metadata;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
